import pygame
import time
import os
import sys
from pathlib import Path
import traceback
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                            QPushButton, QListWidget, QSlider, QLabel, QFileDialog, 
                            QMessageBox, QProgressBar, QGroupBox, QSpinBox, QCheckBox)
from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal
from PyQt5.QtGui import QFont, QIcon, QPixmap

class PlaybackThread(QThread):
    """播放线程，用于处理时间间隔"""
    finished = pyqtSignal()
    
    def __init__(self, interval_seconds):
        super().__init__()
        self.interval_seconds = interval_seconds
        self._is_running = True
        
    def run(self):
        """运行间隔等待"""
        if self.interval_seconds > 0:
            # 分段等待，以便可以中断
            for _ in range(self.interval_seconds * 10):  # 每0.1秒检查一次
                if not self._is_running:
                    break
                time.sleep(0.1)
        self.finished.emit()
    
    def stop(self):
        """停止等待"""
        self._is_running = False

class AudioPlayerGUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.playback_thread = None
        self.init_ui()
        self.init_audio()
        
    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle("音频播放器 - 支持MP3/WAV/OGG")
        self.setGeometry(100, 100, 800, 600)
        
        # 中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        
        # 文件选择区域
        file_group = QGroupBox("文件管理")
        file_layout = QVBoxLayout()
        
        # 文件夹选择按钮
        folder_btn_layout = QHBoxLayout()
        self.folder_label = QLabel("未选择文件夹")
        self.folder_label.setStyleSheet("border: 1px solid gray; padding: 5px;")
        select_folder_btn = QPushButton("选择文件夹")
        select_folder_btn.clicked.connect(self.select_folder)
        folder_btn_layout.addWidget(self.folder_label, 3)
        folder_btn_layout.addWidget(select_folder_btn, 1)
        file_layout.addLayout(folder_btn_layout)
        
        # 文件列表
        self.file_list = QListWidget()
        self.file_list.itemDoubleClicked.connect(self.play_selected_file)
        file_layout.addWidget(QLabel("音频文件列表:"))
        file_layout.addWidget(self.file_list)
        
        file_group.setLayout(file_layout)
        layout.addWidget(file_group)
        
        # 播放控制区域
        control_group = QGroupBox("播放控制")
        control_layout = QVBoxLayout()
        
        # 当前播放信息
        self.current_file_label = QLabel("当前播放: 无")
        self.current_file_label.setStyleSheet("font-weight: bold; color: blue;")
        control_layout.addWidget(self.current_file_label)
        
        # 控制按钮
        btn_layout = QHBoxLayout()
        
        self.prev_btn = QPushButton("上一个 (L)")
        self.prev_btn.clicked.connect(self.play_previous)
        btn_layout.addWidget(self.prev_btn)
        
        self.play_btn = QPushButton("播放")
        self.play_btn.clicked.connect(self.toggle_play)
        btn_layout.addWidget(self.play_btn)
        
        self.pause_btn = QPushButton("暂停 (空格)")
        self.pause_btn.clicked.connect(self.toggle_pause)
        self.pause_btn.setEnabled(False)
        btn_layout.addWidget(self.pause_btn)
        
        self.next_btn = QPushButton("下一个 (N)")
        self.next_btn.clicked.connect(self.play_next)
        btn_layout.addWidget(self.next_btn)
        
        self.stop_btn = QPushButton("停止")
        self.stop_btn.clicked.connect(self.stop_playback)
        btn_layout.addWidget(self.stop_btn)
        
        self.replay_btn = QPushButton("重新播放 (R)")  # 改为重新播放按钮
        self.replay_btn.clicked.connect(self.replay_current)
        self.replay_btn.setEnabled(False)
        btn_layout.addWidget(self.replay_btn)
        
        control_layout.addLayout(btn_layout)
        
        # 音量控制
        volume_layout = QHBoxLayout()
        volume_layout.addWidget(QLabel("音量:"))
        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(70)
        self.volume_slider.valueChanged.connect(self.set_volume)
        volume_layout.addWidget(self.volume_slider)
        self.volume_label = QLabel("70%")
        volume_layout.addWidget(self.volume_label)
        control_layout.addLayout(volume_layout)
        
        # 播放间隔设置
        interval_layout = QHBoxLayout()
        interval_layout.addWidget(QLabel("播放间隔(秒):"))
        self.interval_spin = QSpinBox()
        self.interval_spin.setRange(0, 60)
        self.interval_spin.setValue(3)
        self.interval_spin.valueChanged.connect(self.update_interval)
        interval_layout.addWidget(self.interval_spin)
        
        # 启用间隔复选框
        self.interval_checkbox = QCheckBox("启用间隔")
        self.interval_checkbox.setChecked(True)
        self.interval_checkbox.stateChanged.connect(self.toggle_interval)
        interval_layout.addWidget(self.interval_checkbox)
        
        interval_layout.addStretch()
        control_layout.addLayout(interval_layout)
        
        # 播放模式
        mode_layout = QHBoxLayout()
        mode_layout.addWidget(QLabel("播放模式:"))
        self.loop_checkbox = QCheckBox("循环播放")
        mode_layout.addWidget(self.loop_checkbox)
        self.random_checkbox = QCheckBox("随机播放")
        mode_layout.addWidget(self.random_checkbox)
        mode_layout.addStretch()
        control_layout.addLayout(mode_layout)
        
        control_group.setLayout(control_layout)
        layout.addWidget(control_group)
        
        # 状态栏
        self.status_label = QLabel("就绪")
        self.status_label.setStyleSheet("border: 1px solid gray; padding: 5px;")
        layout.addWidget(self.status_label)
        
        # 初始化变量
        self.audio_files = []
        self.current_index = -1
        self.is_playing = False
        self.is_paused = False
        self.interval_seconds = 3
        self.interval_enabled = True
        self.waiting_for_interval = False
        
        # 设置定时器
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_ui)
        self.timer.start(100)
        
    def init_audio(self):
        """初始化音频系统"""
        try:
            pygame.mixer.init()
            pygame.mixer.music.set_volume(0.7)
            self.update_status("音频系统初始化成功")
        except Exception as e:
            self.show_error(f"音频初始化失败: {e}")
    
    def update_interval(self, value):
        """更新间隔时间"""
        self.interval_seconds = value
    
    def toggle_interval(self, state):
        """切换间隔功能"""
        self.interval_enabled = (state == Qt.Checked)
    
    def select_folder(self):
        """选择文件夹"""
        folder_path = QFileDialog.getExistingDirectory(self, "选择音频文件夹")
        if folder_path:
            self.load_audio_files(folder_path)
    
    def load_audio_files(self, folder_path):
        """加载音频文件"""
        self.folder_label.setText(folder_path)
        self.audio_files = []
        self.file_list.clear()
        
        supported_extensions = ['.mp3', '.wav', '.ogg']
        folder = Path(folder_path)
        
        for ext in supported_extensions:
            files = list(folder.glob(f"*{ext}"))
            for file in files:
                self.audio_files.append(file)
                self.file_list.addItem(file.name)
        
        if self.audio_files:
            self.update_status(f"找到 {len(self.audio_files)} 个音频文件")
            self.play_btn.setEnabled(True)
            self.current_index = 0
            self.highlight_current_file()
        else:
            self.update_status("未找到支持的音频文件")
            self.play_btn.setEnabled(False)
    
    def highlight_current_file(self):
        """高亮显示当前播放的文件"""
        for i in range(self.file_list.count()):
            if i == self.current_index:
                self.file_list.item(i).setBackground(Qt.lightGray)
            else:
                self.file_list.item(i).setBackground(Qt.white)
    
    def play_audio(self, index):
        """播放指定索引的音频文件"""
        if not self.audio_files or index < 0 or index >= len(self.audio_files):
            return
        
        try:
            self.current_index = index
            audio_file = self.audio_files[index]
            
            pygame.mixer.music.load(str(audio_file))
            pygame.mixer.music.play()
            
            self.is_playing = True
            self.is_paused = False
            self.waiting_for_interval = False
            
            self.current_file_label.setText(f"当前播放: {audio_file.name}")
            self.update_status(f"正在播放: {audio_file.name}")
            self.highlight_current_file()
            
            self.play_btn.setText("停止")
            self.pause_btn.setEnabled(True)
            self.pause_btn.setText("暂停")
            self.replay_btn.setEnabled(True)  # 启用重新播放按钮
            
        except Exception as e:
            self.show_error(f"播放失败: {e}")
    
    def replay_current(self):
        """重新播放当前文件"""
        if self.is_playing:
            self.stop_playback()
        if self.audio_files and self.current_index >= 0:
            self.play_audio(self.current_index)
            self.update_status("重新播放当前文件")
    
    def start_interval_wait(self):
        """开始间隔等待"""
        if self.interval_enabled and self.interval_seconds > 0:
            self.waiting_for_interval = True
            self.update_status(f"等待 {self.interval_seconds} 秒后播放下一首...")
            
            # 停止之前的线程
            if self.playback_thread and self.playback_thread.isRunning():
                self.playback_thread.stop()
                self.playback_thread.wait()
            
            # 创建新的等待线程
            self.playback_thread = PlaybackThread(self.interval_seconds)
            self.playback_thread.finished.connect(self.interval_finished)
            self.playback_thread.start()
        else:
            # 没有间隔，直接播放下一个
            self.play_next()
    
    def interval_finished(self):
        """间隔等待完成"""
        if self.waiting_for_interval:
            self.waiting_for_interval = False
            self.play_next()
    
    def toggle_play(self):
        """切换播放/停止状态"""
        if self.is_playing:
            self.stop_playback()
        else:
            if self.audio_files:
                self.play_audio(self.current_index)
    
    def toggle_pause(self):
        """切换暂停/恢复状态"""
        if self.is_playing:
            if self.is_paused:
                pygame.mixer.music.unpause()
                self.is_paused = False
                self.pause_btn.setText("暂停")
                self.update_status("播放恢复")
            else:
                pygame.mixer.music.pause()
                self.is_paused = True
                self.pause_btn.setText("恢复")
                self.update_status("播放暂停")
    
    def stop_playback(self):
        """停止播放"""
        pygame.mixer.music.stop()
        self.is_playing = False
        self.is_paused = False
        self.waiting_for_interval = False
        
        # 停止间隔等待线程
        if self.playback_thread and self.playback_thread.isRunning():
            self.playback_thread.stop()
            self.playback_thread.wait()
        
        self.play_btn.setText("播放")
        self.pause_btn.setEnabled(False)
        self.replay_btn.setEnabled(False)  # 禁用重新播放按钮
        self.update_status("播放停止")
    
    def play_next(self):
        """播放下一个文件"""
        if self.audio_files:
            if self.random_checkbox.isChecked():
                # 随机播放
                import random
                next_index = random.randint(0, len(self.audio_files) - 1)
            else:
                # 顺序播放
                next_index = (self.current_index + 1) % len(self.audio_files)
            
            # 如果是最后一个文件且不循环，则停止
            if next_index == 0 and not self.loop_checkbox.isChecked():
                self.stop_playback()
                self.update_status("播放完成")
            else:
                self.play_audio(next_index)
    
    def play_previous(self):
        """播放上一个文件"""
        if self.audio_files:
            prev_index = (self.current_index - 1) % len(self.audio_files)
            self.play_audio(prev_index)
    
    def play_selected_file(self, item):
        """播放选中的文件"""
        index = self.file_list.row(item)
        self.play_audio(index)
    
    def set_volume(self, value):
        """设置音量"""
        volume = value / 100.0
        pygame.mixer.music.set_volume(volume)
        self.volume_label.setText(f"{value}%")
    
    def update_ui(self):
        """更新UI状态"""
        if self.is_playing and not self.is_paused and not self.waiting_for_interval:
            # 检查是否播放完毕
            if not pygame.mixer.music.get_busy():
                self.start_interval_wait()
    
    def update_status(self, message):
        """更新状态信息"""
        self.status_label.setText(message)
    
    def show_error(self, message):
        """显示错误信息"""
        QMessageBox.critical(self, "错误", message)
        self.update_status(f"错误: {message}")
    
    def keyPressEvent(self, event):
        """键盘事件处理"""
        if event.key() == Qt.Key_Space:
            self.toggle_pause()
        elif event.key() == Qt.Key_N:
            self.play_next()
        elif event.key() == Qt.Key_L:
            self.play_previous()
        elif event.key() == Qt.Key_S:
            self.stop_playback()
        elif event.key() == Qt.Key_R:  # R键重新播放
            self.replay_current()
        elif event.key() == Qt.Key_I:
            # 切换间隔功能
            self.interval_checkbox.setChecked(not self.interval_checkbox.isChecked())
    
    def closeEvent(self, event):
        """关闭事件处理"""
        self.stop_playback()
        pygame.mixer.quit()
        event.accept()

def main():
    # 初始化应用
    app = QApplication(sys.argv)
    
    # 设置应用样式
    app.setStyle('Fusion')
    
    # 创建并显示主窗口
    player = AudioPlayerGUI()
    player.show()
    
    # 运行应用
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()